package com.dirox.jira.notes.issuetab;

import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.jql.builder.JqlQueryBuilder;
import com.atlassian.jira.plugin.webfragment.contextproviders.AbstractJiraContextProvider;
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.security.PermissionManager;
import com.atlassian.jira.security.Permissions;
import com.atlassian.jira.security.groups.GroupManager;
import com.atlassian.jira.security.xsrf.XsrfTokenGenerator;
import com.atlassian.jira.user.util.UserUtil;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.query.Query;
import com.dirox.jira.notes.entities.Note;
import com.dirox.jira.notes.service.NoteService;
import com.dirox.jira.notes.utils.NoteComparator;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;


@SuppressWarnings("unchecked")
public class NoteProvider extends AbstractJiraContextProvider {
	private final JiraAuthenticationContext context;
	private NoteService noteService;
	private SearchService searchService;
	private UserUtil userUtil;
	private GroupManager groupManager;
	private XsrfTokenGenerator xsrfTokenGenerator;
	private com.dirox.jira.notes.utils.JiraHelper jiraHelper;
	private PermissionManager permissionManager;

	public NoteProvider(JiraAuthenticationContext context,
	                    NoteService noteService, SearchService searchService,
	                    XsrfTokenGenerator xsrfTokenGenerator,
	                    UserUtil userUtil, GroupManager groupManager,
	                    PermissionManager permissionManager,
	                    com.dirox.jira.notes.utils.JiraHelper jiraHelper) {
		super();
		this.context = context;
		this.noteService = noteService;
		this.searchService = searchService;
		this.userUtil = checkNotNull(userUtil);
		this.groupManager = checkNotNull(groupManager);
		this.xsrfTokenGenerator = xsrfTokenGenerator;
		this.permissionManager = checkNotNull(permissionManager);
		this.jiraHelper = jiraHelper;
	}

	public List<Issue> getIssues() {
		Query query = JqlQueryBuilder.newClauseBuilder()
		                             .buildQuery();

		try {
			List<Issue> issues = searchService.search(
				context.getLoggedInUser(),
				query,
				PagerFilter.getUnlimitedFilter())
			                                  .getIssues();

			for (Issue issue : issues) {
				if (!permissionManager.hasPermission(
						Permissions.BROWSE,
						issue,
						context.getLoggedInUser())) {
					issues.remove(issue);
				}
			}

			return issues;
		} catch (SearchException e) {
			e.printStackTrace();

			return null;
		}
	}

	@SuppressWarnings({"rawtypes"})
	@Override
	public Map getContextMap(User arg0, JiraHelper helper) {
		Map<String, Object> contextMap = helper.getContextParams();
		List<Issue> issues = getIssues();
		Issue currentIssue = (Issue) helper.getContextParams()
		                                   .get("issue");
		com.dirox.jira.notes.entities.User owner = noteService.currentUser();
		List<Note> notes = noteService.getNotes(currentIssue.getKey(),
		                                        owner);
		List<Note> memos = noteService.getMemos(currentIssue.getKey(),
		                                        owner);
		List<Note> notesAndMemos = new ArrayList<Note>();
		notesAndMemos.addAll(memos);
		notesAndMemos.addAll(notes);

		Collections.sort(notesAndMemos,
		                 new NoteComparator());

		int lastIndex = notesAndMemos.size() - 1;

		SortedSet<User> users = userUtil.getAllUsersInGroups(
			groupManager.getAllGroups());

		if (notesAndMemos.size() > 0) {
			contextMap.put("note",
			               notesAndMemos.get(lastIndex));
		}

		contextMap.put("currentUser",
		               context.getLoggedInUser());
		contextMap.put("issues", issues);
		contextMap.put("users", users);
		contextMap.put("atl_token",
		               xsrfTokenGenerator.generateToken());
		contextMap.put("textutils", jiraHelper);

		return contextMap;
	}
}
